package com.ys.controller.api.storage;

import com.alibaba.fastjson.JSON;
import com.ys.config.MenuId;
import com.ys.entity.storage.TccFbaPlan;
import com.ys.entity.sys.YsCol;
import com.ys.enume.sys.YsColEnum;
import com.ys.service.storage.FbaInboundApiService;
import com.ys.service.storage.TccFbaPlanService;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.UploadService;
import com.ys.util.ExportExcelUtils;
import com.ys.util.admin.ConditionUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @Author: fxz
 * @CreateTime: 2024-12-04
 * @Description: FBA计划单控制层
 * @Version: 1.5
 */
@Controller
@RequestMapping("/api/inter/tccFbaPlan")
public class ApiInterTccFbaPlanController {
    private static final Logger logger = LoggerFactory.getLogger(ApiInterTccFbaPlanController.class);

    @Autowired
    private TccFbaPlanService tccFbaPlanService;

    @Autowired
    private CommonApiService<TccFbaPlan> commonApiService;

    //菜单id
    private Long menuId = MenuId.TCC_FbaPlan;
    private Long menuId1 = MenuId.TCC_FbaPlanX;

    //权限字符
    private final String PERMISSIONS_VIEW = "tccFbaPlan:view";
    private final String PERMISSIONS_ADD = "tccFbaPlan:add";
    private final String PERMISSIONS_DEL = "tccFbaPlan:del";
    private final String PERMISSIONS_EXPORT = "tccFbaPlan:export";
    private final String PERMISSIONS_FLOW = "tccFbaPlan:flow";


    @Autowired
    private FbaInboundApiService fbaInboundApiService;

    /**
     * 设置查询的cond的sql设置
     * @param cond
     * @return
     */
    public TccFbaPlan setSeachSql(TccFbaPlan cond){

        cond.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("CASE WHEN  A.EffectStock = 1 THEN FORMAT(A.UpdateTime, 'yyyy-MM-dd HH:mm:ss') ELSE null END _ys_effectiveTime")//生效时间
                .addField("case when A.declarationState = 0 then '否' else '是' end as declarationStateName")
                .addLeftJoin("TCC_FbaLogisticsMethod C ON C.sourceBid = A.bid AND C.sourceType = 0")
                .addField("C.logsticsWay,C.cck,C.vck,C.transportationCn transportationTypeCn,C.logsticsWayId,C.remark logsticsRemark")
                .addField("case when C.nameLogsticsClearance = 0 then '自税' else '包税' end as nameLogsticsClearanceName")//清关方式
                .addLeftJoin("TCC_FbaFeeDetails D ON D.sourceBid = A.bid AND D.sourceType = 0")
                .addField("D.priceTranPredict,D.priceTranCalWeight,D.priceExtraPredict")
                .addLeftJoin("TCC_FbaPlanItem B ON B.bidFbaPlan = A.bid")
                .addField("B.commodityCode,B.commodityName,B.sku,B.numStock,B.numPlanDeliver,B.isSign,B.signCode,B.annexFile,B.asin,B.fnSku,B.codeGoodsHs,B.nameGoodsCn")
                .addField("B.nameMaterialCn,B.priceIn,B.weightPackage,B.vck,B.vkq,B.vhw")
                .addField("(CONVERT(varchar(19), cast(B.lengthPackage as float)) + '*' + CONVERT(varchar(19), cast(B.widthPackage as float))  + '*' + CONVERT(varchar(19), cast(B.heightPackage as float))) packageSize")
                .addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeId ")
                .addField("U.UserId + '/' + U.UserName AS createUser")//制单人
                .setOrderby("A.Bid DESC");//排序

        cond = commonApiService.dataAuth(menuId, cond);
        return  cond;
    }



    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/search")
    @ResponseBody
    public LayuiTableVoJA search(@ModelAttribute TccFbaPlan cond, String conditions){
        String _ys_effectiveTime = ConditionUtil.getConditionValue(conditions, "_ys_effectiveTime");//生效时间
        if (_ys_effectiveTime != null && _ys_effectiveTime.length() > 0) {
            String[] timeDays = _ys_effectiveTime.split(" ~ ");
            cond.where("P.UpdateTime >= '" + timeDays[0] + "' and P.UpdateTime <= '" + timeDays[1] + "'");
        }
        String _ys_auditingTime = ConditionUtil.getConditionValue(conditions, "_ys_auditingTime");//审核时间
        if (_ys_auditingTime != null && _ys_auditingTime.length() > 0) {
            String[] timeDays = _ys_auditingTime.split(" ~ ");
            cond.where("A.auditingTime >= '" + timeDays[0] + "' and A.auditingTime <= '" + timeDays[1] + "'");
        }
        cond = setSeachSql(cond);

        LayuiTableVoJA vo = commonApiService.searchLay(cond);
        return vo;
    }

    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/searchsearchEstimated")
    @ResponseBody
    public LayuiTableVoJA searchEstimated(@ModelAttribute TccFbaPlan cond, String conditions){
        cond = setSeachSql(cond)
                .addLeftJoin("TCC_FbaFeeDetails Ddd ON Ddd.SourceBid=A.Bid ")
                .where("Ddd.SourceType=0");

        LayuiTableVoJA vo = commonApiService.searchLay(cond);
        return vo;
    }

    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/searchActual")
    @ResponseBody
    public LayuiTableVoJA searchActual(@ModelAttribute TccFbaPlan cond, String conditions){
        cond = setSeachSql(cond)
                .addLeftJoin("TCC_FbaFeeDetails Eee ON Eee.SourceBid=A.Bid ")
                .where("Eee.SourceType=1");

        LayuiTableVoJA vo = commonApiService.searchLay(cond);
        return vo;
    }

    /**
     * 新增
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @RequestMapping("/toAdd")
    @ResponseBody
    public R toSave(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {
            //新增
            return tccFbaPlanService.add(params,menuId);
        } catch (Exception e) {
            logger.error("新增出错：",e.getMessage(),e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error(e.getMessage());
        }
    }

    /**
     * 修改
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @RequestMapping("/toEdit")
    @ResponseBody
    public R toEdit(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {
            //修改
            return tccFbaPlanService.toEdit(params,menuId);
        } catch (Exception e) {
            logger.error("修改出错：",e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 计划删除
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @RequestMapping("/deleteTrue")
    @ResponseBody
    public R deleteTrue(Long id){
        try {
            //计划删除
            return tccFbaPlanService.deleteTrue(id);
        } catch (Exception e) {
            logger.error("计划删除出错：",e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 计划取消
     */
    @RequiresPermissions(PERMISSIONS_DEL)
    @RequestMapping("/delete")
    @ResponseBody
    public R delete(@RequestParam Map<String, Object> params){
        try {
            //计划取消
            return tccFbaPlanService.delete(params);
        } catch (Exception e) {
            logger.error("计划取消出错：",e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /*
     * 导出
     */
    @RequiresPermissions(PERMISSIONS_EXPORT)
    @RequestMapping("/export")
    @ResponseBody
    public R export(@ModelAttribute TccFbaPlan cond, String conditions) throws Exception{

        cond = setSeachSql(cond);
//        cond.addField("");
        String _ys_effectiveTime = ConditionUtil.getConditionValue(conditions, "_ys_effectiveTime");//生效时间
        if (_ys_effectiveTime != null && _ys_effectiveTime.length() > 0) {
            String[] timeDays = _ys_effectiveTime.split(" ~ ");
            cond.where("P.UpdateTime >= '" + timeDays[0] + "' and P.UpdateTime <= '" + timeDays[1] + "'");
        }
        String _ys_auditingTime = ConditionUtil.getConditionValue(conditions, "_ys_auditingTime");//审核时间
        if (_ys_auditingTime != null && _ys_auditingTime.length() > 0) {
            String[] timeDays = _ys_auditingTime.split(" ~ ");
            cond.where("A.auditingTime >= '" + timeDays[0] + "' and A.auditingTime <= '" + timeDays[1] + "'");
        }
        cond.setPage(0).setSize(999999);

        List<Map<String, Object>> listData = cond.queryMap();

        List<YsCol> listField = new YsCol()
                .setMenuId(MenuId.TCC_FbaPlan)
                .setFrontExport(YsColEnum.FrontShow.SHOW.value)
                .setOrderby("A.SortNo asc")
                .queryList();


        ExportExcelUtils<TccFbaPlan> util = new ExportExcelUtils<TccFbaPlan>(new TccFbaPlan());

        String toFilePath = util.exportExcel(listData, listField, "FBA计划单");
        UploadService.UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
        return R.ok(dto.getUrl());
    }

    /**
     * 流转通过
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowPass")
    @ResponseBody
    public R flowPass(HttpServletRequest request, Long id){
        try {
            return tccFbaPlanService.flowPass(id, ShiroUtils.getUserId());
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 流转退回
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowRefuse")
    @ResponseBody
    public R flowRefuse(HttpServletRequest request, Long id, String reason){
        try {
            return tccFbaPlanService.flowRefuse(id, reason, ShiroUtils.getUserId());
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }


    /**
     * 流转驳回
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowInit")
    @ResponseBody
    public R flowInit(HttpServletRequest request, Long id, String reason){
        try {
            return tccFbaPlanService.flowInit(id, reason, ShiroUtils.getUserId());
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 计划审核
     */
    @RequiresPermissions(PERMISSIONS_FLOW)
    @PostMapping("/flow")
    @ResponseBody
    public R flow(HttpServletRequest request, Long id, String reason){
        try {
            return tccFbaPlanService.flow(id);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error(e.getMessage());
        }
    }

    @RequestMapping("/searchFlow")
    @ResponseBody
    public R searchFlow(@ModelAttribute TccFbaPlan cond, String bid){
        try {
            return fbaInboundApiService.searchFlow(bid);
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    @RequestMapping("/searchFlowDetail")
    @ResponseBody
    public R searchFlowDetail(@ModelAttribute TccFbaPlan cond, String bid,String shipmentId){
        try {
            return fbaInboundApiService.searchFlowDetail(bid,shipmentId);
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

    /**
     * 计划审核-sku生成装箱单
     */
    @RequiresPermissions(PERMISSIONS_FLOW)
    @PostMapping("/flowCreate")
    @ResponseBody
    public R flowCreate(HttpServletRequest request,@RequestParam Map<String, Object> params){
        try {
            return tccFbaPlanService.flowCreate(params);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error(e.getMessage());
        }
    }


    /**
     * 设置查询的cond的sql设置
     * @param cond
     * @return
     */
    public TccFbaPlan setSeachSqlNew(TccFbaPlan cond){

        cond.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("CASE WHEN  A.EffectStock = 1 THEN FORMAT(A.UpdateTime, 'yyyy-MM-dd HH:mm:ss') ELSE null END _ys_effectiveTime")//生效时间
                .addField("case when A.declarationState = 0 then '否' else '是' end as declarationStateName")
                .addLeftJoin("TCC_FbaLogisticsMethod C ON C.sourceBid = A.bid AND C.sourceType = 0")
                .addField("C.logsticsWay,C.cck,C.vck,C.transportationCn transportationTypeCn,C.logsticsWayId,C.remark logsticsRemark")
                .addField("case when C.nameLogsticsClearance = 0 then '自税' else '包税' end as nameLogsticsClearanceName")//清关方式
                .addLeftJoin("TCC_FbaFeeDetails D ON D.sourceBid = A.bid AND D.sourceType = 0")
                .addField("D.priceTranPredict,D.priceTranCalWeight,D.priceExtraPredict")
                .addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeId ")
                .addField("U.UserId + '/' + U.UserName AS createUser")//制单人
                .addField("A.status _ys_status")//货件状态
                .setOrderby("A.Bid DESC");//排序

        cond = commonApiService.dataAuth(menuId1, cond);
        return  cond;
    }



    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/searchNew")
    @ResponseBody
    public LayuiTableVoJA searchNew(@ModelAttribute TccFbaPlan cond, String conditions){
        String _ys_effectiveTime = ConditionUtil.getConditionValue(conditions, "_ys_effectiveTime");//生效时间
        if (_ys_effectiveTime != null && _ys_effectiveTime.length() > 0) {
            String[] timeDays = _ys_effectiveTime.split(" ~ ");
            cond.where("P.UpdateTime >= '" + timeDays[0] + "' and P.UpdateTime <= '" + timeDays[1] + "'");
        }
        String _ys_auditingTime = ConditionUtil.getConditionValue(conditions, "_ys_auditingTime");//审核时间
        if (_ys_auditingTime != null && _ys_auditingTime.length() > 0) {
            String[] timeDays = _ys_auditingTime.split(" ~ ");
            cond.where("A.auditingTime >= '" + timeDays[0] + "' and A.auditingTime <= '" + timeDays[1] + "'");
        }
        String _ys_commodityCode = ConditionUtil.getConditionValue(conditions, "_ys_commodityCode");//商品编码
        if (_ys_commodityCode != null && _ys_commodityCode.length() > 0){
            cond.where("(SELECT COUNT(1) FROM TCC_FbaPlanItem DD WHERE DD.commodityCode = '"+ _ys_commodityCode + "')>0 ");
        }

        String _ys_commodityName = ConditionUtil.getConditionValue(conditions, "_ys_commodityName");//商品名称
        if (_ys_commodityName != null && _ys_commodityName.length() > 0){
            cond.where("(SELECT COUNT(1) FROM TCC_FbaPlanItem DD WHERE DD.commodityName LIKE  '%"+ _ys_commodityName + "%') > 0");
        }

        String _ys_status = ConditionUtil.getConditionValue(conditions, "_ys_status");//货件状态
        if (_ys_status != null && _ys_status.length() > 0){
            if (!_ys_status.equals("3")){
                cond.where("A.status = " + _ys_status);
            }
        }
        cond = setSeachSqlNew(cond);

        LayuiTableVoJA vo = commonApiService.searchLay(cond);
        return vo;
    }

    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/searchZb")
    @ResponseBody
    public LayuiTableVoJA searchZb(@ModelAttribute TccFbaPlan cond, String rowConditions){
        TccFbaPlan tccFbaPlan = JSON.parseObject(rowConditions, TccFbaPlan.class);
        cond.addLeftJoin("TCC_FbaPlanItem B ON B.bidFbaPlan = A.bid")
        .addField("B.commodityCode,B.commodityName,B.sku,B.numStock,B.numPlanDeliver,B.isSign,B.signCode,B.annexFile,B.asin,B.fnSku,B.codeGoodsHs,B.nameGoodsCn")
        .addField("B.nameMaterialCn,B.priceIn,B.weightPackage,B.vck,B.vkq,B.vhw,B.numApiDeliver")
        .addField("(CONVERT(varchar(19), cast(B.lengthPackage as float)) + '*' + CONVERT(varchar(19), cast(B.widthPackage as float))  + '*' + CONVERT(varchar(19), cast(B.heightPackage as float))) packageSize");
        if (tccFbaPlan != null) {
            cond.where("B.bidFbaPlan = '" + tccFbaPlan.getBid() + "'");
        }
        LayuiTableVoJA vo = commonApiService.searchLay(cond);
        return vo;
    }

    /*
     * 导出
     */
    @RequiresPermissions(PERMISSIONS_EXPORT)
    @RequestMapping("/exportNew")
    @ResponseBody
    public R exportNew(@ModelAttribute TccFbaPlan cond, String conditions) throws Exception{

        cond = setSeachSqlNew(cond);
        cond.addField("CASE WHEN A.status = 0  THEN '已取消' WHEN A.status = 1  THEN '无'  ELSE '已审核' END  statusName");
        cond.addField("CASE WHEN A.creationMethod = 0  THEN '手动'   ELSE '自动' END  creationMethodName");
        cond.addField("CASE WHEN A.EffectStock = 0  THEN '未生效'   WHEN A.EffectStock = 1  THEN '已生效'  ELSE '已作废' END  effectStockName");
        cond.addField("CASE WHEN A.deliverState = 0  THEN '按箱自动发货'  ELSE '按SKU自动发货' END  deliverStateName");
        String _ys_effectiveTime = ConditionUtil.getConditionValue(conditions, "_ys_effectiveTime");//生效时间
        if (_ys_effectiveTime != null && _ys_effectiveTime.length() > 0) {
            String[] timeDays = _ys_effectiveTime.split(" ~ ");
            cond.where("P.UpdateTime >= '" + timeDays[0] + "' and P.UpdateTime <= '" + timeDays[1] + "'");
        }
        String _ys_auditingTime = ConditionUtil.getConditionValue(conditions, "_ys_auditingTime");//审核时间
        if (_ys_auditingTime != null && _ys_auditingTime.length() > 0) {
            String[] timeDays = _ys_auditingTime.split(" ~ ");
            cond.where("A.auditingTime >= '" + timeDays[0] + "' and A.auditingTime <= '" + timeDays[1] + "'");
        }
        String _ys_commodityCode = ConditionUtil.getConditionValue(conditions, "_ys_commodityCode");//商品编码
        if (_ys_commodityCode != null && _ys_commodityCode.length() > 0){
            cond.where("(SELECT COUNT(1) FROM TCC_FbaPlanItem DD WHERE DD.commodityCode = '"+ _ys_commodityCode + "')>0 ");
        }

        String _ys_commodityName = ConditionUtil.getConditionValue(conditions, "_ys_commodityName");//商品名称
        if (_ys_commodityName != null && _ys_commodityName.length() > 0){
            cond.where("(SELECT COUNT(1) FROM TCC_FbaPlanItem DD WHERE DD.commodityName LIKE  '%"+ _ys_commodityName + "%') > 0");
        }
        String _ys_status = ConditionUtil.getConditionValue(conditions, "_ys_status");//货件状态
        if (_ys_status != null && _ys_status.length() > 0){
            if (!_ys_status.equals("3")){
                cond.where("A.status = " + _ys_status);
            }
        }
        cond.setPage(0).setSize(999999);

        List<Map<String, Object>> listData = cond.queryMap();

        List<YsCol> listField = new YsCol()
                .setMenuId(menuId1)
                .setFrontExport(YsColEnum.FrontExport.SHOW.value)
                .setOrderby("A.SortNo asc")
                .queryList();


        ExportExcelUtils<TccFbaPlan> util = new ExportExcelUtils<TccFbaPlan>(new TccFbaPlan());

        String toFilePath = util.exportExcel(listData, listField, "FBA计划单");
        UploadService.UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
        return R.ok(dto.getUrl());
    }
}
